home *** CD-ROM | disk | FTP | other *** search
/ Mac Magazin/MacEasy 11 / Mac Magazin and MacEasy Magazine CD - Issue 11.iso / Sharewarebibliothek / Entwickler / appe Windows 2.0 / sample drag.c < prev    next >
Text File  |  1995-06-06  |  7KB  |  245 lines

  1. // File "sample drag.c" -
  2.  
  3. #include <Drag.h>
  4.  
  5. #include "main.h"
  6. #include "floaters.h"
  7. #include "sample drag.h"
  8. #include "sample win.h"
  9.  
  10. // ***********************************************************************************
  11. // Global Declarations 
  12.  
  13. extern GlobalsRec glob;
  14.  
  15. // ***********************************************************************************
  16. // ***********************************************************************************
  17.  
  18. void SetupDragHandlers(WindowPtr win) {
  19.     static DragTrackingHandlerUPP trackingHandler=0;
  20.     static DragReceiveHandlerUPP receiveHandler=0;
  21.  
  22.     if (! trackingHandler) trackingHandler = NewDragTrackingHandlerProc(SampleTrackingHandler);
  23.     if (! receiveHandler) receiveHandler = NewDragReceiveHandlerProc(SampleReceiveHandler);
  24.         
  25.     if (trackingHandler && receiveHandler) {
  26.         InstallTrackingHandler(trackingHandler, win, 0);
  27.         InstallReceiveHandler(receiveHandler, win, 0);
  28.         }
  29.     }
  30.  
  31. // ***********************************************************************************
  32. // ***********************************************************************************
  33.  
  34. short SampleWindowDrag(EventRecord *theEvent, WindowPtr win) {
  35.     short err=0;
  36.     Str255 textBuff;
  37.     RgnHandle dragRgn;
  38.     DragReference dragRef=0;
  39.     DragAttributes attributes;
  40.     
  41.     // If the user just clicks and lets go, then return
  42.     if (! WaitMouseMoved(theEvent->where)) return(0);
  43.     
  44.     // Setup the information we need to do a Drag
  45.     err = NewDrag(&dragRef);
  46.     if (err) return(err);
  47.  
  48.     dragRgn = NewDragRgn(win);
  49.     if (!dragRgn) goto HANDLE_ERROR;
  50.  
  51.     // Add in some data - The contents of our window
  52.     BlockMove(GetSampleWindowText(win), textBuff, sizeof(textBuff));
  53.     err = AddDragItemFlavor(dragRef, 1, 'TEXT', textBuff+1, textBuff[0], 0);    
  54.  
  55.  
  56.     // Initiate the dragging process, and handle any errors by escaping
  57.     err = TrackDrag(dragRef, theEvent, dragRgn);
  58.     if (err == userCanceledErr) err = 0;
  59.     if (err) goto HANDLE_ERROR;
  60.     
  61.     GetDragAttributes(dragRef, &attributes);
  62.     if (! (attributes & dragInsideSenderApplication)) {
  63.         AEDesc dropLocation;
  64.  
  65.         GetDropLocation(dragRef, &dropLocation);
  66.  
  67.         AEDisposeDesc(&dropLocation);
  68.         }
  69.  
  70.     
  71. HANDLE_ERROR:
  72.     if (dragRef) DisposeDrag(dragRef);
  73.     if (dragRgn) DisposeRgn(dragRgn);
  74.     return(err);
  75.     }
  76.  
  77. // ***********************************************************************************
  78. // ***********************************************************************************
  79.  
  80. pascal OSErr SampleTrackingHandler(DragTrackingMessage message, WindowPtr win,
  81.         void *refcon, DragReference dragRef) {
  82.     static Boolean acceptDrag, inContent;
  83.     short err=0;
  84.     unsigned short count;
  85.     unsigned long flavorFlags;
  86.     Size dataSize;
  87.     Point localPt;
  88.     GrafPtr savePort;
  89.     RgnHandle hiliteRgn;
  90.     ItemReference dragItem;
  91.     DragAttributes attributes;
  92.     
  93.     GetDragAttributes(dragRef, &attributes);
  94.     
  95.     GetPort(&savePort);
  96.     SetPort(win);
  97.     
  98.     switch (message) {
  99.         case dragTrackingEnterHandler:
  100.             acceptDrag = FALSE;
  101.             inContent = FALSE;
  102.             break;
  103.             
  104.         case dragTrackingEnterWindow:
  105.             // Test *every* Drag Item to see if it contains text or a text file.
  106.             //   (The sample code in the Drag Mgr dox suggested this, but I think
  107.             //   that you could probably reorganize it for whatever your needs are.)
  108.             if (CountDragItems(dragRef, &count)) count=0;
  109.             for(count, acceptDrag = TRUE; count && acceptDrag; count--) {
  110.                 GetDragItemReferenceNumber(dragRef, count, &dragItem);
  111.                 
  112.                 if (! GetFlavorFlags(dragRef, dragItem, 'TEXT', &flavorFlags)) continue;
  113.                 if (! GetFlavorFlags(dragRef, dragItem, 'hfs ', &flavorFlags)) {
  114.                     HFSFlavor hfsDataBuff;
  115.                     
  116.                     dataSize = sizeof(hfsDataBuff);
  117.                     err = GetFlavorData(dragRef, dragItem, 'hfs ', (Ptr) &hfsDataBuff, &dataSize, 0L);
  118.                     if (! err && (hfsDataBuff.fileType == 'TEXT')) continue;
  119.                     }
  120.                 
  121.                 acceptDrag = FALSE;
  122.                 }
  123.             break;
  124.  
  125.         case dragTrackingInWindow:
  126.             if (! acceptDrag) break;
  127.             
  128.             GetDragMouse(dragRef, &localPt, 0L);
  129.             GlobalToLocal(&localPt);
  130.             
  131.             if (attributes & dragHasLeftSenderWindow) {
  132.                 if (! inContent) {
  133.                     if (hiliteRgn = NewRgn()) {
  134.                         RectRgn(hiliteRgn, &win->portRect);
  135.                         ShowDragHilite(dragRef, hiliteRgn, TRUE);
  136.                         DisposeRgn(hiliteRgn);
  137.                         }
  138.                     inContent = TRUE;
  139.                     }
  140.                 }
  141.               else {
  142.                 if (inContent) {
  143.                     HideDragHilite(dragRef);
  144.                     inContent = FALSE;
  145.                     }
  146.                 }
  147.             break;
  148.         case dragTrackingLeaveWindow:
  149.             if (acceptDrag && inContent) HideDragHilite(dragRef);
  150.             acceptDrag = FALSE;
  151.             inContent = FALSE;
  152.             break;
  153.         case dragTrackingLeaveHandler:
  154.             break;
  155.         }
  156.  
  157.     SetPort(savePort);
  158.     }
  159.  
  160. // ***********************************************************************************
  161. // ***********************************************************************************
  162.  
  163. pascal OSErr SampleReceiveHandler(WindowPtr win, void *refcon, DragReference dragRef) {
  164.     Boolean handled;
  165.     unsigned short index, count;
  166.     unsigned long flavorFlags;
  167.     Size dataSize;
  168.     Str255 textBuff;
  169.     GrafPtr savePort;
  170.     ItemReference dragItem;
  171.     DragAttributes attributes;
  172.  
  173.     // As above, we test every Drag Item to see if it contains text or text file. 
  174.     //   However, we simply find and use the first match (as the new window contents).
  175.     if (CountDragItems(dragRef, &count)) count=0;
  176.     for(index=1, handled=FALSE; (index<=count) && !handled; index++) {
  177.         GetDragItemReferenceNumber(dragRef, index, &dragItem);
  178.         
  179.         if (! GetFlavorFlags(dragRef, dragItem, 'TEXT', &flavorFlags)) {
  180.             GetFlavorDataSize(dragRef, dragItem, 'TEXT', &dataSize);
  181.             textBuff[0] = dataSize = (dataSize <= 255) ? dataSize : 255;
  182.             GetFlavorData(dragRef, dragItem, 'TEXT', (Ptr) textBuff+1, &dataSize, 0L);
  183.             handled = TRUE; continue;
  184.             }
  185.         
  186.         if (! GetFlavorFlags(dragRef, dragItem, 'hfs ', &flavorFlags)) {
  187.             short refNum, err=0;
  188.             HFSFlavor hfsDataBuff;
  189.             
  190.             dataSize = sizeof(hfsDataBuff);
  191.             err = GetFlavorData(dragRef, dragItem, 'hfs ', (Ptr) &hfsDataBuff, &dataSize, 0L);
  192.             if (hfsDataBuff.fileType != 'TEXT') err=-1;    // Only look at text files
  193.             if (! err) err = FSpOpenDF(&hfsDataBuff.fileSpec, fsRdPerm, &refNum);
  194.               else refNum = 0;
  195.             
  196.             dataSize = 255;
  197.             if (! err) err = FSRead(refNum, &dataSize, textBuff+1);
  198.             if (err == eofErr) err = 0;    // Short files are OK, ignore this error
  199.             if (refNum) FSClose(refNum);
  200.             
  201.             if (! err) textBuff[0] = dataSize;
  202.             if (! err) { handled = TRUE; continue; }
  203.             }
  204.         }
  205.     
  206.     if (handled) {
  207.         // Update the window, then help our app handle the event quickly.
  208.         //   (If you notice, we may be in someone else's context!)
  209.         SetSampleWindowText(win, textBuff);
  210.         WakeUpProcess(&glob.myPSN);
  211.         }
  212.     return((handled) ? 0 : -1);
  213.     }
  214.  
  215. // ***********************************************************************************
  216. // ***********************************************************************************
  217.  
  218. RgnHandle NewDragRgn(WindowPtr win) {
  219.     Point convertPt;
  220.     GrafPtr savePort;
  221.     RgnHandle dragRgn=0, tempRgn=0;
  222.     
  223.     dragRgn = NewRgn();
  224.     tempRgn = NewRgn();
  225.     if (! dragRgn || ! tempRgn) return(0);
  226.     
  227.     // Build up a region that's 1 pixel thick, as per Drag Mgr dox
  228.     RectRgn(dragRgn, &win->portRect);
  229.     InsetRgn(dragRgn, 3, 3);
  230.     CopyRgn(dragRgn, tempRgn);
  231.     InsetRgn(tempRgn, 1, 1);
  232.     DiffRgn(dragRgn, tempRgn, dragRgn);
  233.     DisposeRgn(tempRgn);
  234.     
  235.     // Convert the coords of our rgn (ala PortRect) from Local to Global
  236.     GetPort(&savePort);
  237.     SetPort(win);
  238.     SetPt(&convertPt, 0, 0);
  239.     LocalToGlobal(&convertPt);
  240.     SetPort(savePort);
  241.     OffsetRgn(dragRgn, convertPt.h, convertPt.v);
  242.     
  243.     return(dragRgn);
  244.     }
  245.